// ==UserScript==
// @name         Userscript01
// @namespace    https://bbs.tampermonkey.net.cn/
// @version      0.4.0
// @description  Capture sessionkey from API response and save to sessionStorage
// @author       You
// @match        http://10.24.0.11/*
// @grant        GM_xmlhttpRequest
// @connect      10.24.0.11
// @connect      *
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';
    
    // 防止重复执行
    if (window._scriptInitialized) {
        console.log('[WARN] Script already initialized, skipping');
        return;
    }
    window._scriptInitialized = true;
    
    // 标识当前窗口类型
    const isIframe = window.top !== window;
    const windowType = isIframe ? 'IFRAME' : 'MAIN';
    
    console.log(`\n${'='.repeat(80)}`);
    console.log(`[INIT ${windowType}] Script starting`);
    console.log(`[INIT ${windowType}] URL: ${window.location.href}`);
    console.log(`${'='.repeat(80)}\n`);
    
    // 配置
    const TARGET_PATH = '/api/workflow/customQuery/getQueryResultKey';
    const SESSIONKEY_STORAGE_KEY = 'workflow_sessionkey';
    
    // 用于重放请求的变量
    let capturedRequest = null;
    
    // 提取并保存 sessionkey 的函数
    function extractAndSaveSessionKey(responseText, source) {
        try {
            console.log(`[${windowType}] Attempting to extract sessionkey from ${source}`);
            console.log(`[${windowType}] Response preview:`, responseText.substring(0, 300));
            
            const responseData = JSON.parse(responseText);
            
            if (responseData && responseData.sessionkey) {
                const sessionkey = responseData.sessionkey;
                
                // 保存到 sessionStorage
                sessionStorage.setItem(SESSIONKEY_STORAGE_KEY, sessionkey);
                
                // 同时保存到 window 对象供访问
                window._currentSessionKey = sessionkey;
                
                console.log(`[${windowType}] 🔑✅ SessionKey SAVED!`);
                console.log(`[${windowType}] 🔑 Value: ${sessionkey}`);
                console.log(`[${windowType}] 🔑 sessionStorage['${SESSIONKEY_STORAGE_KEY}'] = ${sessionkey}`);
                console.log(`[${windowType}] 🔑 window._currentSessionKey = ${sessionkey}`);
                
                // 验证保存成功
                const saved = sessionStorage.getItem(SESSIONKEY_STORAGE_KEY);
                console.log(`[${windowType}] 🔑 Verification - Retrieved from sessionStorage: ${saved}`);
                
                return sessionkey;
            } else {
                console.warn(`[${windowType}] ⚠️ SessionKey not found in response`);
                console.warn(`[${windowType}] Response data:`, responseData);
                return null;
            }
        } catch (e) {
            console.error(`[${windowType}] ❌ Failed to extract sessionkey:`, e);
            console.error(`[${windowType}] Response text:`, responseText);
            return null;
        }
    }
    
    // 用 GM_xmlhttpRequest 重放请求以绕过 CORS 限制
    function replayRequest() {
        if (!capturedRequest) {
            console.log(`[${windowType}][REPLAY] No captured request to replay`);
            return;
        }
        
        console.log(`\n${'='.repeat(80)}`);
        console.log(`[${windowType}][REPLAY] 🔄 REPLAYING REQUEST TO CAPTURE RESPONSE`);
        console.log(`[${windowType}][REPLAY] URL: ${capturedRequest.url}`);
        console.log(`[${windowType}][REPLAY] Method: ${capturedRequest.method}`);
        console.log(`${'='.repeat(80)}\n`);
        
        const headers = capturedRequest.requestHeaders || {};
        
        // 确保有正确的 Content-Type
        if (capturedRequest.requestBody && !headers['Content-Type']) {
            headers['Content-Type'] = 'application/json';
        }
        
        // 准备请求体
        let bodyToSend = capturedRequest.requestBody;
        if (typeof bodyToSend === 'object' && bodyToSend !== null) {
            bodyToSend = JSON.stringify(bodyToSend);
        }
        
        console.log(`[${windowType}][REPLAY] 📦 Request Headers:`, headers);
        console.log(`[${windowType}][REPLAY] 📦 Request Body:`, capturedRequest.requestBody);
        
        GM_xmlhttpRequest({
            method: capturedRequest.method,
            url: capturedRequest.url,
            data: bodyToSend,
            headers: headers,
            onload: function(response) {
                console.log(`\n${'='.repeat(80)}`);
                console.log(`[${windowType}][REPLAY] ✅ RESPONSE CAPTURED FROM REPLAY!`);
                console.log(`[${windowType}][REPLAY] Status: ${response.status} ${response.statusText}`);
                console.log(`${'='.repeat(80)}\n`);
                
                try {
                    if (response.status === 200 && response.responseText) {
                        // 解析并显示响应JSON
                        const responseData = JSON.parse(response.responseText);
                        
                        console.log(`[${windowType}][REPLAY] 📄 RESPONSE JSON:`);
                        console.log(responseData);
                        
                        // 格式化显示JSON（如果对象较大）
                        console.log(`\n[${windowType}][REPLAY] 📄 FORMATTED RESPONSE JSON:`);
                        console.log(JSON.stringify(responseData, null, 2));
                        
                        // 从重放的响应中提取 sessionkey
                        extractAndSaveSessionKey(response.responseText, 'GM_xmlhttpRequest-replay');
                        
                        console.log(`\n${'='.repeat(80)}`);
                        console.log(`[${windowType}][REPLAY] ✅ Response processing complete!`);
                        console.log(`${'='.repeat(80)}\n`);
                    } else {
                        console.warn(`\n${'='.repeat(80)}`);
                        console.warn(`[${windowType}][REPLAY] ⚠️ UNEXPECTED RESPONSE STATUS: ${response.status}`);
                        console.warn(`[${windowType}][REPLAY] Status Text: ${response.statusText}`);
                        console.warn(`[${windowType}][REPLAY] Response Text:`, response.responseText);
                        console.warn(`${'='.repeat(80)}\n`);
                    }
                } catch (e) {
                    console.error(`\n${'='.repeat(80)}`);
                    console.error(`[${windowType}][REPLAY] ❌ FAILED TO PARSE RESPONSE`);
                    console.error(`[${windowType}][REPLAY] Error:`, e);
                    console.error(`[${windowType}][REPLAY] Raw Response Text:`, response.responseText);
                    console.error(`${'='.repeat(80)}\n`);
                }
            },
            onerror: function(error) {
                console.error(`\n${'='.repeat(80)}`);
                console.error(`[${windowType}][REPLAY] ❌ REQUEST REPLAY FAILED`);
                console.error(`[${windowType}][REPLAY] Error:`, error);
                console.error(`${'='.repeat(80)}\n`);
            },
            ontimeout: function() {
                console.error(`\n${'='.repeat(80)}`);
                console.error(`[${windowType}][REPLAY] ❌ REQUEST REPLAY TIMEOUT`);
                console.error(`${'='.repeat(80)}\n`);
            }
        });
    }
    
    // 保存原始的 XMLHttpRequest
    const OriginalXHR = window.XMLHttpRequest;
    const originalOpen = OriginalXHR.prototype.open;
    const originalSend = OriginalXHR.prototype.send;
    const originalSetRequestHeader = OriginalXHR.prototype.setRequestHeader;
    
    // 创建响应属性拦截器
    function setupResponseInterceptor(xhr, url) {
        // 拦截 response 和 responseText 属性
        let actualResponse = null;
        let actualResponseText = null;
        
        Object.defineProperty(xhr, 'response', {
            get: function() {
                if (actualResponse === null && this.readyState === 4) {
                    actualResponse = Object.getOwnPropertyDescriptor(OriginalXHR.prototype, 'response').get.call(this);
                    if (url.includes(TARGET_PATH) && actualResponse) {
                        console.log(`[${windowType}][RESPONSE-GETTER] Target response accessed!`);
                        const responseText = typeof actualResponse === 'string' ? actualResponse : JSON.stringify(actualResponse);
                        extractAndSaveSessionKey(responseText, 'response-getter');
                    }
                }
                return actualResponse !== null ? actualResponse : Object.getOwnPropertyDescriptor(OriginalXHR.prototype, 'response').get.call(this);
            },
            configurable: true
        });
        
        Object.defineProperty(xhr, 'responseText', {
            get: function() {
                if (actualResponseText === null && this.readyState === 4) {
                    actualResponseText = Object.getOwnPropertyDescriptor(OriginalXHR.prototype, 'responseText').get.call(this);
                    if (url.includes(TARGET_PATH) && actualResponseText) {
                        console.log(`[${windowType}][RESPONSETEXT-GETTER] Target responseText accessed!`);
                        extractAndSaveSessionKey(actualResponseText, 'responseText-getter');
                    }
                }
                return actualResponseText !== null ? actualResponseText : Object.getOwnPropertyDescriptor(OriginalXHR.prototype, 'responseText').get.call(this);
            },
            configurable: true
        });
    }
    
    // 拦截 setRequestHeader 以捕获请求头
    OriginalXHR.prototype.setRequestHeader = function(header, value) {
        if (!this._requestHeaders) {
            this._requestHeaders = {};
        }
        this._requestHeaders[header] = value;
        return originalSetRequestHeader.apply(this, arguments);
    };
    
    // 拦截 XHR
    OriginalXHR.prototype.open = function(method, url, ...args) {
        // 规范化 URL
        let normalizedUrl;
        try {
            normalizedUrl = new URL(url, location.href).toString();
        } catch (e) {
            normalizedUrl = String(url);
        }
        
        this._interceptedUrl = normalizedUrl;
        this._interceptedMethod = method;
        this._requestHeaders = {}; // 初始化请求头对象
        
        if (normalizedUrl.includes(TARGET_PATH)) {
            console.log(`[${windowType}][XHR] 🎯 TARGET REQUEST: ${method} ${normalizedUrl}`);
            
            // 设置响应拦截器
            setupResponseInterceptor(this, normalizedUrl);
            
            // 保存原始事件处理器
            const originalOnReadyStateChange = this.onreadystatechange;
            const originalOnLoad = this.onload;
            const originalOnLoadEnd = this.onloadend;
            
            // 拦截 onreadystatechange
            this.onreadystatechange = function() {
                if (this.readyState === 4 && this.status === 200) {
                    console.log(`[${windowType}][XHR] 🎯 TARGET RESPONSE (onreadystatechange)!`);
                    if (this.responseText) {
                        extractAndSaveSessionKey(this.responseText, 'onreadystatechange');
                    }
                }
                if (originalOnReadyStateChange) {
                    return originalOnReadyStateChange.apply(this, arguments);
                }
            };
            
            // 拦截 onload
            this.onload = function() {
                console.log(`[${windowType}][XHR] 🎯 TARGET RESPONSE (onload)!`);
                if (this.responseText) {
                    extractAndSaveSessionKey(this.responseText, 'onload');
                }
                if (originalOnLoad) {
                    return originalOnLoad.apply(this, arguments);
                }
            };
            
            // 拦截 onloadend
            this.onloadend = function() {
                console.log(`[${windowType}][XHR] 🎯 TARGET RESPONSE (onloadend)!`);
                if (this.responseText) {
                    extractAndSaveSessionKey(this.responseText, 'onloadend');
                }
                if (originalOnLoadEnd) {
                    return originalOnLoadEnd.apply(this, arguments);
                }
            };
            
            // 添加事件监听器
            this.addEventListener('readystatechange', function() {
                if (this.readyState === 4 && this.status === 200) {
                    console.log(`[${windowType}][XHR] 🎯 TARGET RESPONSE (addEventListener readystatechange)!`);
                    if (this.responseText) {
                        extractAndSaveSessionKey(this.responseText, 'addEventListener-readystatechange');
                    }
                }
            });
            
            this.addEventListener('load', function() {
                console.log(`[${windowType}][XHR] 🎯 TARGET RESPONSE (addEventListener load)!`);
                if (this.responseText) {
                    extractAndSaveSessionKey(this.responseText, 'addEventListener-load');
                }
            });
            
            this.addEventListener('loadend', function() {
                console.log(`[${windowType}][XHR] 🎯 TARGET RESPONSE (addEventListener loadend)!`);
                if (this.responseText) {
                    extractAndSaveSessionKey(this.responseText, 'addEventListener-loadend');
                }
            });
        }
        
        return originalOpen.apply(this, [method, url, ...args]);
    };
    
    OriginalXHR.prototype.send = function(body) {
        const xhr = this;
        
        if (this._interceptedUrl && this._interceptedUrl.includes(TARGET_PATH)) {
            console.log(`[${windowType}][XHR] 🎯 Sending target request...`);
            console.log(`[${windowType}][XHR] URL: ${this._interceptedUrl}`);
            console.log(`[${windowType}][XHR] Method: ${this._interceptedMethod}`);
            console.log(`[${windowType}][XHR] Body:`, body);
            
            // 捕获请求信息用于重放
            capturedRequest = {
                method: this._interceptedMethod,
                url: this._interceptedUrl,
                requestBody: body,
                requestHeaders: this._requestHeaders || {}
            };
            
            console.log(`[${windowType}][XHR] 📦 Request captured for replay`);
            
            // 添加 load 事件监听器，在请求完成后立即重放
            xhr.addEventListener('load', function() {
                console.log(`[${windowType}][XHR] 🎯 Original request completed, initiating replay...`);
                // 延迟一小段时间再重放，确保原始请求已完成
                setTimeout(() => {
                    replayRequest();
                }, 100);
            });
            
            // 也尝试从原始响应中提取（虽然可能因 CORS 失败）
            xhr.addEventListener('loadend', function() {
                if (this.responseText) {
                    console.log(`[${windowType}][XHR] 📄 Attempting to read original response (may fail due to CORS)...`);
                    try {
                        extractAndSaveSessionKey(this.responseText, 'original-xhr');
                    } catch (e) {
                        console.log(`[${windowType}][XHR] ℹ️ Could not read original response (expected if CORS restricted):`, e.message);
                    }
                }
            });
        }
        
        return originalSend.apply(this, arguments);
    };
    
    // 拦截 Fetch
    const originalFetch = window.fetch;
    window.fetch = async function(...args) {
        let resource = args[0];
        const config = args[1];
        
        let urlString;
        try {
            if (resource && typeof resource === 'object' && resource.url) {
                urlString = new URL(resource.url, location.href).toString();
            } else {
                urlString = new URL(String(resource), location.href).toString();
            }
        } catch (e) {
            urlString = String(resource);
        }
        
        const isTarget = urlString.includes(TARGET_PATH);
        
        if (isTarget) {
            console.log(`[${windowType}][FETCH] 🎯 TARGET REQUEST: ${urlString}`);
        }
        
        try {
            const response = await originalFetch.apply(this, args);
            
            if (isTarget) {
                console.log(`[${windowType}][FETCH] 🎯 TARGET RESPONSE received!`);
                
                // Clone response to read it
                const responseClone = response.clone();
                const responseText = await responseClone.text();
                
                extractAndSaveSessionKey(responseText, 'fetch');
            }
            
            return response;
        } catch (error) {
            console.error(`[${windowType}][FETCH] Error:`, error);
            throw error;
        }
    };
    
    // 监控网络活动（Performance API）
    if (window.PerformanceObserver) {
        const observer = new PerformanceObserver((list) => {
            for (const entry of list.getEntries()) {
                if (entry.name.includes(TARGET_PATH)) {
                    console.log(`[${windowType}][PERF] 🎯 Detected target request via Performance API:`, entry.name);
                    console.log(`[${windowType}][PERF] Entry details:`, {
                        name: entry.name,
                        duration: entry.duration,
                        startTime: entry.startTime
                    });
                    
                    // 如果XHR/Fetch拦截器没有捕获到请求，使用Performance API数据作为后备
                    if (!capturedRequest) {
                        console.log(`[${windowType}][PERF] ⚠️ Request not captured by XHR/Fetch interceptors, creating fallback request`);
                        capturedRequest = {
                            method: 'GET',  // Performance API无法获取method，默认使用GET
                            url: entry.name,
                            requestBody: null,
                            requestHeaders: {}
                        };
                        
                        // 延迟执行重放，确保请求已完成
                        setTimeout(() => {
                            console.log(`[${windowType}][PERF] 🔄 Initiating fallback replay from Performance API detection...`);
                            replayRequest();
                        }, 200);
                    }
                }
            }
        });
        
        try {
            observer.observe({ entryTypes: ['resource', 'navigation'] });
            console.log(`[${windowType}] Performance Observer started`);
        } catch (e) {
            console.warn(`[${windowType}] Performance Observer failed:`, e);
        }
    }
    
    // 添加全局检查函数
    window.checkSessionKey = function() {
        console.log('\n=== SESSION KEY STATUS ===');
        console.log('sessionStorage:', sessionStorage);
        console.log(`sessionStorage['${SESSIONKEY_STORAGE_KEY}']:`, sessionStorage.getItem(SESSIONKEY_STORAGE_KEY));
        console.log('window._currentSessionKey:', window._currentSessionKey);
        console.log('sessionStorage.length:', sessionStorage.length);
        console.log('All sessionStorage keys:');
        for (let i = 0; i < sessionStorage.length; i++) {
            const key = sessionStorage.key(i);
            console.log(`  ${key}:`, sessionStorage.getItem(key));
        }
        console.log('==========================\n');
        return sessionStorage.getItem(SESSIONKEY_STORAGE_KEY);
    };
    
    console.log(`\n${'='.repeat(80)}`);
    console.log(`[${windowType}] ✅ Initialization complete!`);
    console.log(`[${windowType}] Target path: ${TARGET_PATH}`);
    console.log(`[${windowType}] Storage key: ${SESSIONKEY_STORAGE_KEY}`);
    console.log(`[${windowType}] Run checkSessionKey() to check status`);
    console.log(`${'='.repeat(80)}\n`);
    
})();
